#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Vulkan Performance Profiling System - 集成验证脚本
用于检查性能插桩系统是否正确集成到项目中
"""

import os
import sys
import re

class Colors:
    """终端颜色"""
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    BLUE = '\033[94m'
    END = '\033[0m'
    BOLD = '\033[1m'

def print_success(msg):
    print(f"{Colors.GREEN}✓{Colors.END} {msg}")

def print_warning(msg):
    print(f"{Colors.YELLOW}⚠{Colors.END} {msg}")

def print_error(msg):
    print(f"{Colors.RED}✗{Colors.END} {msg}")

def print_info(msg):
    print(f"{Colors.BLUE}ℹ{Colors.END} {msg}")

def print_section(title):
    print(f"\n{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}")
    print(f"{Colors.BOLD}{title}{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}\n")

def check_file_exists(filepath, description):
    """检查文件是否存在"""
    if os.path.exists(filepath):
        print_success(f"{description}: {filepath}")
        return True
    else:
        print_error(f"{description} 不存在: {filepath}")
        return False

def check_file_content(filepath, pattern, description):
    """检查文件内容是否包含特定模式"""
    try:
        with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
            if re.search(pattern, content):
                print_success(f"{description}")
                return True
            else:
                print_error(f"{description} - 未找到模式")
                return False
    except Exception as e:
        print_error(f"读取文件失败 {filepath}: {e}")
        return False

def verify_core_files():
    """验证核心文件"""
    print_section("1. 验证核心文件")
    
    files_to_check = [
        ("entry/src/main/cpp/Common/PerformanceProfiler.hpp", "性能分析器头文件"),
        ("entry/src/main/cpp/Common/PerformanceProfiler.cpp", "性能分析器实现文件"),
        ("entry/src/main/cpp/Common/VulkanProfilingWrapper.hpp", "Vulkan包装宏头文件"),
    ]
    
    results = []
    for filepath, desc in files_to_check:
        results.append(check_file_exists(filepath, desc))
    
    return all(results)

def verify_integration():
    """验证代码集成"""
    print_section("2. 验证代码集成")
    
    checks = [
        ("entry/src/main/cpp/Begin/hellovk.cpp", 
         r"#include\s+<PerformanceProfiler\.hpp>",
         "hellovk.cpp 包含 PerformanceProfiler.hpp"),
        
        ("entry/src/main/cpp/Begin/hellovk.cpp",
         r"#include\s+<VulkanProfilingWrapper\.hpp>",
         "hellovk.cpp 包含 VulkanProfilingWrapper.hpp"),
        
        ("entry/src/main/cpp/Begin/hellovk.cpp",
         r"PROFILE_PIPELINE_STAGE\(FrameStart\)",
         "hellovk.cpp 使用 PROFILE_PIPELINE_STAGE"),
        
        ("entry/src/main/cpp/Begin/hellovk.cpp",
         r"PROFILE_API_CALL\(",
         "hellovk.cpp 使用 PROFILE_API_CALL"),
        
        ("entry/src/main/cpp/Begin/hellovk.cpp",
         r"PerformanceProfiler::Instance\(\)\.Enable",
         "hellovk.cpp 启用性能分析器"),
        
        ("entry/src/main/cpp/Begin/hellovk.cpp",
         r"PerformanceProfiler::Instance\(\)\.ExportToFile",
         "hellovk.cpp 导出性能数据"),
        
        ("entry/src/main/cpp/CMakeLists.txt",
         r"common/PerformanceProfiler\.cpp",
         "CMakeLists.txt 包含 PerformanceProfiler.cpp"),
    ]
    
    results = []
    for filepath, pattern, desc in checks:
        results.append(check_file_content(filepath, pattern, desc))
    
    return all(results)

def verify_documentation():
    """验证文档"""
    print_section("3. 验证文档")
    
    docs = [
        ("PERFORMANCE_PROFILING_README.md", "完整文档"),
        ("QUICKSTART.md", "快速开始指南"),
        ("QUICK_REFERENCE.md", "快速参考卡"),
        ("IMPLEMENTATION_SUMMARY.md", "实现总结"),
        ("README_PROFILING.md", "项目README"),
        ("analyze_performance.py", "性能分析工具"),
    ]
    
    results = []
    for filepath, desc in docs:
        results.append(check_file_exists(filepath, desc))
    
    return all(results)

def count_instrumentation_points():
    """统计插桩点数量"""
    print_section("4. 统计插桩点")
    
    files_to_check = [
        "entry/src/main/cpp/Begin/hellovk.cpp",
        "entry/src/main/cpp/vulkan_utils/MainSceneRenderer.cpp",
    ]
    
    total_profile_api_call = 0
    total_profile_pipeline_stage = 0
    
    for filepath in files_to_check:
        if not os.path.exists(filepath):
            continue
        
        try:
            with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
                content = f.read()
                profile_api_call = len(re.findall(r'PROFILE_API_CALL\(', content))
                profile_pipeline_stage = len(re.findall(r'PROFILE_PIPELINE_STAGE\(', content))
                
                if profile_api_call > 0 or profile_pipeline_stage > 0:
                    print_info(f"{os.path.basename(filepath)}:")
                    if profile_api_call > 0:
                        print(f"  - PROFILE_API_CALL: {profile_api_call} 处")
                    if profile_pipeline_stage > 0:
                        print(f"  - PROFILE_PIPELINE_STAGE: {profile_pipeline_stage} 处")
                    
                    total_profile_api_call += profile_api_call
                    total_profile_pipeline_stage += profile_pipeline_stage
        except Exception as e:
            print_error(f"读取文件失败 {filepath}: {e}")
    
    print()
    print_success(f"总计 PROFILE_API_CALL: {total_profile_api_call} 处")
    print_success(f"总计 PROFILE_PIPELINE_STAGE: {total_profile_pipeline_stage} 处")
    
    return total_profile_api_call + total_profile_pipeline_stage > 0

def check_api_coverage():
    """检查API覆盖"""
    print_section("5. 检查 API 冒烟测试覆盖")
    
    filepath = "entry/src/main/cpp/Begin/hellovk.cpp"
    if not os.path.exists(filepath):
        print_error(f"文件不存在: {filepath}")
        return False
    
    # 检查关键API + 冒烟测试函数的存在
    critical_apis = [
        "vkCreateGraphicsPipelines",
        "vkQueueSubmit",
        "vkQueuePresentKHR",
        "vkAcquireNextImageKHR",
        "vkWaitForFences",
        "vkCmdDraw",
        "vkUpdateDescriptorSets",
        "vkCreateRenderPass",
        "vkCmdBeginRenderPass",
        "vkCmdEndRenderPass",
    ]
    
    # 冒烟测试中额外的API
    smoke_test_apis = [
        "vkGetPipelineCacheData",
        "vkGetPrivateData",
        "vkGetQueryPoolResults",
        "vkGetRenderAreaGranularity",
        "vkGetSemaphoreCounterValue",
        "vkInvalidateMappedMemoryRanges",
        "vkMergePipelineCaches",
        "vkQueueBindSparse",
        "RunApiSmokeTestsOnce",  # 主要的冒烟测试函数
    ]
    
    try:
        with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
            
            found_critical = 0
            for api in critical_apis:
                if api in content:
                    found_critical += 1
            
            found_smoke = 0
            for api in smoke_test_apis:
                if api in content:
                    found_smoke += 1
            
            print_info(f"关键 Vulkan API 覆盖: {found_critical}/{len(critical_apis)}")
            print_info(f"冒烟测试 API 覆盖: {found_smoke}/{len(smoke_test_apis)}")
            
            # 检查RunApiSmokeTestsOnce函数是否存在
            has_smoke_tests = "RunApiSmokeTestsOnce" in content
            
            if has_smoke_tests:
                print_success(f"✓ 发现 RunApiSmokeTestsOnce() 函数 (包含100+ Vulkan API冒烟测试)")
                print_success(f"✓ 关键API覆盖: {found_critical}/{len(critical_apis)}")
                print_success(f"✓ 冒烟测试API覆盖: {found_smoke}/{len(smoke_test_apis)}")
                return True
            elif found_critical >= len(critical_apis) * 0.8:  # 80% 关键API覆盖
                print_success("API 覆盖率良好")
                return True
            else:
                print_warning(f"API 覆盖率偏低: 关键API {found_critical}/{len(critical_apis)}, 冒烟测试API {found_smoke}/{len(smoke_test_apis)}")
                return False
    except Exception as e:
        print_error(f"读取文件失败: {e}")
        return False

def generate_report():
    """生成验证报告"""
    print_section("验证报告")
    
    print(f"{Colors.BOLD}验证项目:{Colors.END}")
    print("  1. 核心文件 (PerformanceProfiler, VulkanProfilingWrapper)")
    print("  2. 代码集成 (include语句, 宏使用, CMakeLists)")
    print("  3. 文档完整性 (README, 快速开始, 分析工具)")
    print("  4. 插桩点统计 (PROFILE_API_CALL, PROFILE_PIPELINE_STAGE)")
    print("  5. API覆盖检查 (关键Vulkan API)")
    print()
    
    results = {
        "核心文件": verify_core_files(),
        "代码集成": verify_integration(),
        "文档完整性": verify_documentation(),
        "插桩点统计": count_instrumentation_points(),
        "API覆盖": check_api_coverage(),
    }
    
    print_section("验证结果")
    
    passed = 0
    failed = 0
    
    for check_name, result in results.items():
        if result:
            print_success(f"{check_name}: 通过")
            passed += 1
        else:
            print_error(f"{check_name}: 失败")
            failed += 1
    
    print()
    print(f"{Colors.BOLD}总体结果:{Colors.END}")
    print(f"  通过: {Colors.GREEN}{passed}{Colors.END} / {passed + failed}")
    print(f"  失败: {Colors.RED}{failed}{Colors.END} / {passed + failed}")
    
    if all(results.values()):
        print()
        print_success(f"{Colors.BOLD}🎉 所有验证项通过! 系统已正确集成。{Colors.END}")
        print()
        print_info("下一步:")
        print("  1. 编译项目: hvigorw assembleHap")
        print("  2. 运行应用并测试")
        print("  3. 导出性能数据")
        print("  4. 使用 analyze_performance.py 分析数据")
        print()
        return True
    else:
        print()
        print_error(f"{Colors.BOLD}❌ 验证失败! 请检查失败项并修复。{Colors.END}")
        print()
        print_info("请参考文档:")
        print("  - PERFORMANCE_PROFILING_README.md (完整文档)")
        print("  - QUICKSTART.md (快速开始)")
        print()
        return False

def main():
    """主函数"""
    print()
    print(f"{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}")
    print(f"{Colors.BOLD}Vulkan Performance Profiling System{Colors.END}")
    print(f"{Colors.BOLD}集成验证脚本{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}{'='*60}{Colors.END}")
    
    # 检查当前目录
    if not os.path.exists("entry") or not os.path.exists("hvigorfile.ts"):
        print_error("请在项目根目录运行此脚本")
        print_info("当前目录应包含: entry/, hvigorfile.ts 等")
        sys.exit(1)
    
    # 运行验证
    success = generate_report()
    
    # 返回退出码
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()
